package com.coolingme.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import com.coolingme.service.TestService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * 如下方式会使@Async失效
 * 一、异步方法使用static修饰
 * 二、异步类没有使用@Component注解（或其他注解）导致spring无法扫描到异步类
 * 三、异步方法不能与异步方法在同一个类中
 * 四、类中需要使用@Autowired或@Resource等注解自动注入，不能自己手动new对象
 * 五、如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解
 * 六、在Async 方法上标注@Transactional是没用的。 在Async 方法调用的方法上标注@Transactional 有效。
 * 七、调用被@Async标记的方法的调用者不能和被调用的方法在同一类中不然不会起作用！！！！！！！
 * 八、使用@Async时要求是不能有返回值的不然会报错的 因为异步要求是不关心结果的
 */
@Slf4j
@Service
public class TestServiceImpl implements TestService {

    /**
     * 如果有自定义的线程池就使用
     */
    @Async
    @Override
    public void asyncMethod() {
        log.info("{} syncMethod异步处理开始...", Thread.currentThread().getName());
        ThreadUtil.sleep(3000);
        log.info("{} syncMethod异步处理结束", Thread.currentThread().getName());
    }

    /**
     * 默认情况下，Spring将搜索相关的线程池定义：
     * 要么在上下文中搜索唯一的TaskExecutor bean，
     * 要么搜索名为“taskExecutor”的Executor bean。
     * 如果两者都无法解析，则将使用SimpleAsyncTaskExecutor来处理异步方法调用。
     */
    @Async("taskExecutor")  // 如果找不到taskExecutor的Bean，则将使用SimpleAsyncTaskExecutor来处理异步方法调用
//    @Async("myTaskExecutor")
    @Override
    public void asyncMethod2() {
        log.info("{} syncMethod2异步处理开始...", Thread.currentThread().getName());
        ThreadUtil.sleep(3000);
        log.info("{} syncMethod2异步处理结束", Thread.currentThread().getName());
    }

}
